//*****************************************************************************
//
// Copyright, (C) 2000-2005 Quantic Dream SA
//
// These coded instructions, statements and computer programs contain
// unpublished information, proprietary to Quantic Dream SA and are 
// protected by French and EEC copyright laws. They may not be 
// disclosed to third parties or copied or duplicated, in whole or in part, 
// without prior written consent of Quantic Dream SA
//
// Unpublished-rights reserved under the Copyright Laws of the EEC.
//
//*****************************************************************************
//
//	CLASS:	SHADER
//
//	JJA : 2012-07-23 - Created
//*****************************************************************************

#include "Shader.h"

#include <QFile>
#include <QMessageBox>

//=============================================================================
//	CODE STARTS HERE
//=============================================================================

//-----------------------------------------------------------------------------
//! @brief		SHADER constructor
//! @details		
//! @param		
//! @return		
//! @author		JJA : 2012-07-23
//-----------------------------------------------------------------------------
SHADER::SHADER()
: _uiVertexShaderId		( GL_INVALID_INDEX )
, _uiPixelShaderId		( GL_INVALID_INDEX )
, _uiShaderProgramId	( GL_INVALID_INDEX )
{
	
}

//-----------------------------------------------------------------------------
//! @brief		SHADER destructor
//! @details		
//! @param		
//! @return		
//! @author		JJA : 2012-07-23
//-----------------------------------------------------------------------------
SHADER::~SHADER()
{
	
}

//-----------------------------------------------------------------------------
//! @brief		Load
//! @details		
//! @param		
//! @return		
//! @author		JJA : 2012-07-25
//-----------------------------------------------------------------------------
void	SHADER::Load(const char *	pcVertexShaderPath,
					 const char *	pcFragmentShaderPath)
{
	_uiVertexShaderId	= LoadShaderFile( GL_VERTEX_SHADER, pcVertexShaderPath );
	_uiPixelShaderId	= LoadShaderFile( GL_FRAGMENT_SHADER, pcFragmentShaderPath );
	_uiShaderProgramId	= CreateProgram( _uiVertexShaderId, _uiPixelShaderId );
}

//-----------------------------------------------------------------------------
//! @brief		LoadShaderFile
//! @details		
//! @param		
//! @return		
//! @author		JJA : 2012-07-19
//-----------------------------------------------------------------------------
GLuint	SHADER::LoadShaderFile(const GLenum	eShaderType,
							   const char *	pcShaderPath)
{
	QFile shaderFile( pcShaderPath );

	if	( shaderFile.open( QIODevice::ReadOnly ) == false )
	{
		QMessageBox msgBox( QMessageBox::Critical, "Shader loading error", "Error loading shader at the following path: " + QString( pcShaderPath ), QMessageBox::Ok );
		msgBox.exec();

		return	( GL_INVALID_INDEX );
	}

	QByteArray		shaderBytes	= shaderFile.readAll();
	GLuint			uiShaderId	= glCreateShader( eShaderType );
	const GLchar*	pcShader	= (const GLchar*)shaderBytes.constData();

	glShaderSource( uiShaderId, 1, &pcShader, NULL );
	glCompileShader( uiShaderId );

	GLint nResult;
	glGetShaderiv( uiShaderId, GL_COMPILE_STATUS, &nResult );

	if	( nResult == GL_FALSE )
	{
		int infologLength = 0;
		int charsWritten  = 0;
		char *infoLog;

		glGetShaderiv( uiShaderId, GL_INFO_LOG_LENGTH, &infologLength );

		QMessageBox msgBox( QMessageBox::Critical, "Shader compilation error", "Error compiling shader at the following path: " + QString( pcShaderPath ), QMessageBox::Ok );

		if (infologLength > 0)
		{
			infoLog = new char[infologLength];
			glGetShaderInfoLog( uiShaderId, infologLength, &charsWritten, infoLog );
			//printf("%s\n",infoLog);
			msgBox.setInformativeText( infoLog );
			delete infoLog;
		}

		msgBox.exec();

		return	( GL_INVALID_INDEX );
	}

	return	( uiShaderId );
}

//-----------------------------------------------------------------------------
//! @brief		CreateProgram
//! @details		
//! @param		
//! @return		
//! @author		JJA : 2012-07-19
//-----------------------------------------------------------------------------
GLuint	SHADER::CreateProgram(const GLuint	uiVertexShaderId,
							  const GLuint	uiPixelShaderId)
{
	GLuint uiProgramId = glCreateProgram();

	glAttachShader( uiProgramId, uiVertexShaderId );
	glAttachShader( uiProgramId, uiPixelShaderId );
	glLinkProgram( uiProgramId );

	GLint nResult;
	glGetProgramiv( uiProgramId, GL_LINK_STATUS, &nResult );

	if	( nResult == GL_FALSE )
	{
		return	( GL_INVALID_INDEX );
	}

	return	( uiProgramId );
}

//=============================================================================
//	CODE ENDS HERE
//=============================================================================
